﻿package eu.liquify.ui {
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import no.doomsday.console.ConsoleUtil;
	public class ListBox extends UIContainer {
		public static var childAliases:Object = { "item": ListItem };
		
		public var select:Function = NULL_FUNCTION;
		
		protected var labelTxt:Label = new Label();
		public var spacing:Number = 3;
		
		public var active:ListItem;
		private var collapsed:Boolean = true;
		private var items:Vector.<ListItem> = new Vector.<ListItem>();
		//private var shadow:GlowFilter = new GlowFilter(0x000000, 0);
		private var _activeData:Object;
		public var gridWidth:Number = 50;
		public var gridHeight:Number = 25;
		public var pairAutoSwitch:Boolean = true;
		
		private var contentOffset:Point = new Point();
		
		public function ListBox() {
			labelTxt.fixedSize = false;
			labelTxt.padding = 0;
			label = "";
			addRawChild(labelTxt);
		}
		
		override public function set label(value:String):void {
			super.label = value;
			labelTxt.label = label;
			labelTxt.y = gridHeight/2-labelTxt.height/2;
			if (label == "") {
				labelTxt.visible = false;
				contentOffset.x = 0;
			} else {
				labelTxt.visible = true;
				contentOffset.x = labelTxt.width+spacing;
			}
			updateContentPosition();
		}
		
		override public function addChild(child:DisplayObject):DisplayObject {
			if (child is ListItem) {
				var m:ListItem = child as ListItem;
				m.fixedSize = true;
				m.stretchH = true;
				m.width = gridWidth;
				m.resize();
				m.alpha = 0;
				super.addChild(m);
				m.mouseChildren = m.mouseEnabled = false;
				m.addEventListener(MouseEvent.CLICK, itemClick);
				items.push(m);
				if (items.length == 1) {
					switchTo(m);
					active = m;
				}
			} else {
				super.addChild(child);
			}
			
			return child;
		}
		
		override public function removeChild(child:DisplayObject):DisplayObject {
			if (child is ListItem) {
				var index:int = items.indexOf(m);
				if (index > -1) {
					var m:ListItem = child as ListItem;
					m.removeEventListener(MouseEvent.CLICK, itemClick);
					items.splice(index, 1);
				}
			} else {
				super.removeChild(child);
			}
			
			return child;
		}
		
		public function get activeData():Object { return _activeData; }
		
		public function set activeData(value:Object):void {
			for (var i:int = 0; i < items.length; i++) {
				var m:ListItem = items[i];
				if (m.data == value) {
					_activeData = value;
					active = m;
					switchTo(m);
					break;
				}
			}
		}
		
		private function switchTo(item:ListItem):void {
			items[items.indexOf(item)] = items[0];
			items[0] = item;
			
			if (!collapsed) collapse();
			
			setChildIndex(item, numChildren-1);
			
			item.mouseChildren = item.mouseEnabled = true;
			TweenNano.to(item, 0.1, { "alpha": 1, "x": 0, "y": 0 } );
		}
		private function itemClick(e:MouseEvent):void {
			var item:ListItem = e.currentTarget as ListItem;
			var i:int;
			var m:ListItem;
			if (collapsed && !(pairAutoSwitch && items.length == 2)) {
				collapsed = false;
				for (i = 0; i < items.length; i++) {
					m = items[i];
					//m.filters = [shadow];
					if (m == item) continue;
					
					m.mouseChildren = m.mouseEnabled = true;
					super.addChild(m);
					
					TweenNano.to(m, 0.1, { "alpha": 1, "y": i*gridHeight } );
				}
				
				removeRawChild(content);
				updateContentPosition();
				stage.addChild(content);
				
				redraw();
				
				stage.addEventListener(MouseEvent.MOUSE_UP, stageCollapse);
			} else {
				if (pairAutoSwitch && items.length == 2) {
					item = item == items[0] ? items[1] : items[0];
				}
				switchTo(item);
				if (active != item) {
					active = item;
					_activeData = active.data;
					Utils.callDynamic(select, this);
					dispatchEvent(new ListEvent(ListEvent.SELECT, item));
				}
			}
		}
		
		private function stageCollapse(e:MouseEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_UP, stageCollapse);
			var cur:DisplayObject = e.target as DisplayObject;
			while (cur) {
				var index:int = items.indexOf(cur);
				if (index > -1) {
					return;
				}
				cur = cur.parent;
			}
			switchTo(active);
		}
		
		private function collapse():void {
			if (!collapsed) {
				collapsed = true;
				var i:int;
				var m:ListItem;
				for (i = 0; i < items.length; i++) {
					m = items[i];
					//m.filters = [];
					m.mouseChildren = m.mouseEnabled = false;
					
					TweenNano.to(m, 0.1, { "alpha": 0, "x": 0, "y": 0 } );
				}
				
				stage.removeChild(content);
				updateContentPosition();
				addRawChild(content);
				
				redraw(false);
			}
		}
		
		private function updateContentPosition():void {
			if (collapsed) {
				content.x = contentOffset.x;
				content.y = contentOffset.y;
			} else {
				var p:Point = localToGlobal(contentOffset);
				content.x = p.x;
				content.y = p.y;
			}
		}
		
		private function redraw(draw:Boolean = true):void {
			var g:Graphics = content.graphics;
			g.clear();
			if (draw) {
				g.lineStyle(1, 0xDDDDDD, 1, true);
				g.beginFill(0xF8F8FC);
				//g.drawRoundRect(-3, -4, gridWidth+6, items.length*gridHeight+6, 6, 6);
				g.drawRoundRect(-6, -6, gridWidth+12, items.length*gridHeight+10, 6, 6);
			}
		}
		
	}
}